﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Data.Common;


namespace EasyMapping.Core
{
    public class SQLDataProvider: IDataProvider
    {
        #region " Private Contructor "

        private SQLDataProvider()
        {
            this.ProviderType = Providers.SQLSERVER;
        }
      
        #endregion

        #region " Store Procedure "

        DbDataReader IDataProvider.ProvideDataByProcedure(DbCommand cmd, string cmdText, Dictionary<string, IProcedureParameter> commonParameters)
        {
            cmd.CommandType = System.Data.CommandType.StoredProcedure;
            cmd.CommandText = cmdText;
            foreach (var item in commonParameters)
            {
                ((SqlCommand)cmd).Parameters.Add(item.Key, ((SQLProcedureParameterWrapper)item.Value).type);
                ((SqlCommand)cmd).Parameters[item.Key].Value = item.Value.value;
            }

            DbDataReader reader = cmd.ExecuteReader();
            return reader;
        }

        int IDataProvider.ChangeDataByProcedure(DbCommand cmd, string cmdText, Dictionary<string, IProcedureParameter> commonParameters, object obj)
        {
            cmd.CommandType = System.Data.CommandType.StoredProcedure;
            cmd.CommandText = cmdText;

            int outputParas = 0;
            foreach (var item in commonParameters)
            {
                SQLProcedureParameterWrapper temp = (SQLProcedureParameterWrapper)item.Value;
                ((SqlCommand)cmd).Parameters.Add(item.Key, temp.type);
                ((SqlCommand)cmd).Parameters[item.Key].Value = item.Value.value;
                if (temp.IsOutput)
                {
                    cmd.Parameters[item.Key].Direction = System.Data.ParameterDirection.Output;
                    temp.SQLClientParameter = ((SqlCommand)cmd).Parameters[item.Key];
                    outputParas++;
                }
            }

            int count = cmd.ExecuteNonQuery();
            if (outputParas != 0)
            {
                foreach (var item in commonParameters)
                {
                    SQLProcedureParameterWrapper temp = (SQLProcedureParameterWrapper)item.Value;
                    if (temp.IsOutput)
                    {
                        temp.propertyInfo.SetValue(obj, temp.SQLClientParameter.Value, null);
                    }
                }
            }
            return count;
        }

        #endregion

        #region IDataProvider Members

        IStoreProcedure IDataFactory.CreateProcedure()
        {
            return new SQLStoredProcedure();
        }

        IProcedureParameter IDataFactory.CreateProcedureParameter()
        {
            return new SQLProcedureParameterWrapper();
        }

        Dictionary<string, IProcedureParameter> IDataFactory.CreateProcedureParameterList()
        {
            return new Dictionary<string, IProcedureParameter>();
        }

        public Providers ProviderType { get; set; }

        #endregion
    }
}
